package com.ruoyi.common.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.R;

import com.ruoyi.common.entity.Category;
import com.ruoyi.common.entity.ProjectItem;
import com.ruoyi.common.entity.dto.CategoryDTO;
import com.ruoyi.common.entity.dto.SelectCategoryDto;
import com.ruoyi.common.mapper.ProjectItemMapper;
import com.ruoyi.common.mapper.WebCategoryMapper;
import com.ruoyi.common.service.IWebCategoryService;
import com.ruoyi.common.service.ProjectItemService;
import com.ruoyi.common.service.ProjectService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 项目/内容分类表 服务实现类
 */
@Service
public class WebCategoryServiceImpl extends ServiceImpl<WebCategoryMapper, Category> implements IWebCategoryService {

    @Override
    public R<List<Category>> getAllCategories() {
        try {
            List<Category> categories = this.list();
            return R.ok(categories);
        } catch (Exception e) {
            // 记录日志
            return R.fail("获取分类列表失败");
        }
    }

    @Override
    public R<Category> getCategoryById(Integer id) {
        try {
            Category category = this.getById(id);
            if (category != null) {
                return R.ok(category);
            } else {
                return R.fail("分类未找到");
            }
        } catch (Exception e) {
            // 记录日志
            return R.fail("查询分类失败");
        }
    }

    @Override
    @Transactional // 保证数据一致性
    public R<Category> createCategory(CategoryDTO categoryDTO) {
        try {
            Category category = new Category();
            BeanUtils.copyProperties(categoryDTO, category);
            // TODO: 从安全上下文获取 createBy 和 updateBy
            category.setCreatedAt(LocalDateTime.now());
            category.setUpdatedAt(LocalDateTime.now());

            boolean saved = this.save(category);
            if (saved) {
                return R.ok(category, "分类创建成功");
            } else {
                return R.fail("分类创建失败");
            }
        } catch (Exception e) {
            // 记录日志
            return R.fail("分类创建过程中发生错误");
        }
    }

    @Override
    @Transactional // 保证数据一致性
    public R<Category> updateCategory(Integer id, CategoryDTO categoryDTO) {
        try {
            Category existingCategory = this.getById(id);
            if (existingCategory == null) {
                return R.fail("要更新的分类不存在");
            }

            Category categoryToUpdate = new Category();
            BeanUtils.copyProperties(categoryDTO, categoryToUpdate, "id"); // 忽略ID
            categoryToUpdate.setId(id); // 保留原ID
            // TODO: 从安全上下文获取 updateBy
            categoryToUpdate.setUpdatedAt(LocalDateTime.now());

            boolean updated = this.updateById(categoryToUpdate);
            if (updated) {
                Category updatedCategory = this.getById(id); // 获取更新后的完整对象
                return R.ok(updatedCategory, "分类更新成功");
            } else {
                return R.fail("分类更新失败");
            }
        } catch (Exception e) {
            // 记录日志
            return R.fail("分类更新过程中发生错误");
        }
    }

    @Override
    @Transactional // 保证数据一致性
    public R<Void> deleteCategory(Integer id) {
        try {
            boolean removed = this.removeById(id);
            if (removed) {
                return R.ok(null, "分类删除成功");
            } else {
                return R.fail("分类删除失败，可能分类不存在");
            }
        } catch (Exception e) {
             // 记录日志 (考虑外键约束等)
            return R.fail("分类删除过程中发生错误");
        }
    }

    @Override
    public R<Page<Category>> getCategoryPage(int pageNum, int pageSize) {
        try {
            Page<Category> page = new Page<>(pageNum, pageSize);
            Page<Category> categoryPage = this.page(page);
            return R.ok(categoryPage);
        } catch (Exception e) {
            // 记录日志
            return R.fail("分页查询分类失败");
        }
    }

    @Override
    public R<List<Category>> searchCategoriesByName(String name) {
         try {
            QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
            queryWrapper.like("title", name);
            List<Category> categories = this.list(queryWrapper);
            return R.ok(categories);
        } catch (Exception e) {
            // 记录日志
            return R.fail("搜索分类失败");
        }
    }
    @Override
    public List<Category> selectCategoryList(Category category) {
        QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
        if (category != null) {
            if (category.getTitle() != null && !category.getTitle().isEmpty()) {
                queryWrapper.like("title", category.getTitle());
            }
            if (category.getIsActive() != null) {
                queryWrapper.eq("is_active", category.getIsActive());
            }
        }
        return this.list(queryWrapper);
    }
    @Autowired
    private ProjectItemMapper projectItemMapper;
    @Override
    public int deleteCategoryByIds(Long[] ids) {
        for (Long id : ids) {
            ProjectItem projectItem = projectItemMapper.selectOne(Wrappers.<ProjectItem>lambdaQuery()
                    .eq(ProjectItem::getCategoryId, id));
            if (ObjectUtil.isNotNull(projectItem)){
                throw new RuntimeException("请先删除该分类下的项目");
            }
        }
        ArrayList<Long> list = CollUtil.toList(ids);
        return baseMapper.deleteBatchIds(list);

    }

    @Override
    public List<SelectCategoryDto> getCategory() {
        List<Category> categories = this.baseMapper.selectList(null);
        return categories.stream().map(category -> {
            SelectCategoryDto selectCategoryDto = new SelectCategoryDto();
            selectCategoryDto.setId(category.getId());
            selectCategoryDto.setTitle(category.getTitle());
            return selectCategoryDto;
        }).collect(Collectors.toList());
    }
}